package com.sc.byahi.user.client.components.maps;

import com.google.gwt.core.client.JavaScriptObject;
import com.google.gwt.event.shared.HandlerRegistration;

public class Marker extends MVCObject<Marker> {

	protected Marker() {
	}

	public static Marker getInstance(MarkerOptions options) {
		return createJso(options).cast();
	}

	private static final native JavaScriptObject createJso(MarkerOptions options) /*-{
		return new $wnd.google.maps.Marker(options);
	}-*/;

	public final void setMap(MapWidget mapWidget) {
		if (mapWidget == null) {
			close();
		} else {
			setMapImpl(mapWidget.getJso());
		}
	}

	private final native void setMapImpl(MapImpl map) /*-{
		this.setMap(map);
	}-*/;

	public final native LatLng getPosition() /*-{
		return this.getPosition();
	}-*/;

	/**
	 * Close the marker. Clear the marker from the map.
	 */
	public final native void close() /*-{
		this.setMap();
	}-*/;

	/**
	 * Close the marker. Clear the marker from the map.
	 */
	public final native void clear() /*-{
		this.setMap();
	}-*/;

	public final native String getTitle() /*-{
		return this.getTitle();
	}-*/;

	// public final HandlerRegistration addClickHandler(ClickMapHandler handler) {
	// return MapHandlerRegistration.addHandler(this, MapEventType.CLICK, handler, new ClickEventFormatter());
	// }

	public final HandlerRegistration addClickHandler(MClickHandler handler) {

		final JavaScriptObject listener = addHandlerImpl(this, "click", handler);

		HandlerRegistration registration = new HandlerRegistration() {
			@Override
			public void removeHandler() {
				removeHandlerImpl(listener);
			}
		};
		return registration;
	}

	private static native void removeHandlerImpl(JavaScriptObject listener) /*-{
		$wnd.google.maps.event.removeListener(listener);
	}-*/;

	private static native JavaScriptObject addHandlerImpl(JavaScriptObject jso, String eventName, MClickHandler handler) /*-{
		var callback = function(event) {
			$entry(@com.sc.byahi.user.client.components.maps.MClickHandlerRegistration::onCallback(Lcom/sc/byahi/user/client/components/maps/MClickHandler;Lcom/google/gwt/ajaxloader/client/Properties;)(handler, event));
		};
		return $wnd.google.maps.event.addListener(jso, eventName, callback)
	}-*/;
	
	public final HandlerRegistration addDragEndHandler(MDragEndHandler handler) {
		
		final JavaScriptObject listener = addDragEndHandlerImpl(this, "dragend", handler);
		
		HandlerRegistration registration = new HandlerRegistration() {
			@Override
			public void removeHandler() {
				removeHandlerImpl(listener);
			}
		};
		return registration;
	}
	
	private static native void removeDragEndHandlerImpl(JavaScriptObject listener) /*-{
		$wnd.google.maps.event.removeListener(listener);
	}-*/;
	
	private static native JavaScriptObject addDragEndHandlerImpl(JavaScriptObject jso, String eventName, MDragEndHandler handler) /*-{
		var callback = function(event) {
			$entry(@com.sc.byahi.user.client.components.maps.MDragEndHandlerRegistration::onCallback(Lcom/sc/byahi/user/client/components/maps/MDragEndHandler;Lcom/google/gwt/ajaxloader/client/Properties;)(handler, event));
		};
		return $wnd.google.maps.event.addListener(jso, eventName, callback)
	}-*/;

	private static native JavaScriptObject getSingletonCallback(JavaScriptObject jso, String eventName, MClickHandler handler) /*-{
		var callback = function(event) {
			$entry(@com.sc.byahi.user.client.components.maps.MClickHandlerRegistration::onCallback(Lcom/sc/byahi/user/client/components/maps/MClickHandler;Lcom/google/gwt/ajaxloader/client/Properties;)(handler, event));
		};
		return callback;
	}-*/;

	private static native JavaScriptObject registerSIngletonAsListener(JavaScriptObject jso) /*-{
		return $wnd.google.maps.event.addListener(jso, eventName, callback)
	}-*/;

	public final native void setAnimation(Integer animation) /*-{
		this.setAnimation(animation);
	}-*/;

}
